package com.qingluan.dd;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import com.baidu.location.BDLocation;
import com.baidu.location.BDLocationListener;
import com.baidu.mapapi.BMapManager;
import com.baidu.mapapi.map.ItemizedOverlay;
import com.baidu.mapapi.map.LocationData;
import com.baidu.mapapi.map.MapController;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.map.MyLocationOverlay;
import com.baidu.mapapi.map.Overlay;
import com.baidu.mapapi.map.OverlayItem;
import com.baidu.platform.comapi.basestruct.GeoPoint;
import com.qingluan.Database.MissionDataBase;
import com.qingluan.Database.Personal_Info_database;
import com.qingluan.arguments.ARGUMENTS;
import com.qingluan.geo.BaiduLocationServer;
import com.qingluan.server.BroadCastRecevier;
import com.qingluan.server.GeoService;
import com.qingluan.server.BroadCastRecevier.ReceiveListener;
import com.qingluan.widget.TimeHelper;

import de.tavendo.autobahn.WebSocketMessage.Pong;

import android.nfc.Tag;
import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.text.Layout;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.webkit.GeolocationPermissions;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.Toast;

public class MapPartnerLocation extends Activity {
	private String[] attendees ;
	private String tag = this.getClass().getName();
	private Context context_this_activity ;
	//map argu area
	private MapView mapView ;
	private BMapManager mapManager ;
	private MapController mapController;
	private BaiduLocationServer LocationServer ;
	private Intent intent_to_start_service ;
	
	private HashMap<String, GeoPoint> geoPointList ;
	private List<HashMap<String, String>> usersGeo;
	private LinearLayout partner_bt_area;
	private IntentFilter filter; 
	
	
	private GeoPoint this_place;
	//context argu area
	private BroadCastRecevier broadCastRecevier;
	private String obj_id;
	private String uid;
	private boolean ifBuild = false;
	private boolean ifOpen = false;
	
	private Drawable mark;
	private CustomOverlay itemOverlay ;
	private GeoPoint LocateFirst = null;
	//people info argu context
	
	private LoginThread loginThread ;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		mapManager = new BMapManager(getApplication());
		mapManager.init("Ei38G5wOcSolTE7LXhDf0eNj",null);
		setContentView(R.layout.activity_map_partner_location);
		context_this_activity = getApplicationContext();
		
		obj_id = getIntent().getStringExtra("mission_id");
		uid = getIntent().getStringExtra("uid");
		
		mapView = (MapView)findViewById(R.id.map_partner);
		partner_bt_area = (LinearLayout)findViewById(R.id.partner_area);
		
		geoPointList  = new HashMap<String,GeoPoint>();
		usersGeo = new ArrayList<HashMap<String,String>>();
		
		mapController = mapView.getController();
		mapController.setZoom(14);
		
		broadCastRecevier = new BroadCastRecevier();
		filter = new IntentFilter();
		filter.addAction(ARGUMENTS.GEO_LOCATION_SERVICE_RECE);
		
		mark= getResources().getDrawable(R.drawable.mark);
		mark.setBounds(0, 0, mark.getIntrinsicWidth(), mark.getIntrinsicHeight());
		itemOverlay = new CustomOverlay(mark, mapView);
		
		loginThread = new LoginThread();
		
		intent_to_start_service = new Intent(MapPartnerLocation.this,GeoService.class);
		registerReceiver(broadCastRecevier, filter);
		ReciveInfo();
		//test
		getFirstLocation();
		
	}
	
	public void getAndUpdateLocation(){
		Log.d(tag,"start..");
		
		for (HashMap<String, String> oneItem : usersGeo){
			Log.d(tag,"loading ...data ...");
			Log.d(tag,oneItem.get("name"));
			OverlayItem item = new OverlayItem(geoPointList.get(oneItem.get("name")),oneItem.get("name"),oneItem.get("time") );
			item.setMarker(mark);
			itemOverlay.addItem(item);
		}
		mapView.getOverlays().clear();
		mapView.getOverlays().add(itemOverlay);
		
		mapView.refresh();
	}
	
	@Override
	protected void onDestroy() {
		// TODO Auto-generated method stub
		loginThread.OFF();
		mapView.destroy();
		if (mapManager!= null){
			try{
				mapManager.destroy();
				mapManager = null;
			}catch (NullPointerException e){
				Log.d(tag, e.toString());
			}
		}
		unregisterReceiver(broadCastRecevier);
		super.onDestroy();

	}
	@Override
	protected void onPause() {
		// TODO Auto-generated method stub
		Log.d(tag, "pause");
		Exit();
		ifBuild = false;
		ifOpen = false;
		mapView.onPause();  
		LocationServer.qLocationClient.stop();

		if (mapManager != null){
			 mapManager.stop();
		}
		super.onPause();
	}

	@Override
	protected void onResume() {
		// TODO Auto-generated method stub
		Log.d(tag,"service startup");
		
		mapView.onResume();
		if(LocationServer != null){
			LocationServer.qLocationClient.start();
		}
		GetLocation();
		
		if (mapManager != null){
			mapManager.start();
		}
		super.onResume();
	}
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.map_partner_location, menu);
		return true;
	}

	private void ReciveInfo(){
		context_this_activity.startService(intent_to_start_service);

		Log.d(tag, "broad receiver startup");
		if (broadCastRecevier != null){
			Log.d(tag, "loading module to startup");
			broadCastRecevier.setReceiveListenr(new ReceiveListener(){

				@Override
				public void receive(String info) {
					// TODO Auto-generated method stub
					Log.d(tag,"receive from service "+info);
					if (info.equals("ON")){
						Log.d(tag, "start log in");
						ifBuild =true;
						Login();
					}else if (info.equals("OFF")){
						
					}else{
						
						try {
							JSONObject jsonInfo = new JSONObject(info);
							String status = jsonInfo.getString("status");
							
							/*
							 * to deal with json data..
							 */
							Log.d(tag, "status"+status);
							if(status.equals("add_to_talk_list")){
								JSONArray jsonArray = jsonInfo.getJSONArray("attendees");
								for (int i =0 ;i < jsonArray.length();i++){
									JSONObject oneObject = jsonArray.getJSONObject(i);
									String time = oneObject.getString("time");
									String name = oneObject.getString("name");
									int lat = oneObject.getInt("lat");
									int lon = oneObject.getInt("lon");
									GeoPoint oneP = new GeoPoint(lat, lon);
									HashMap<String, String> oneUser = new HashMap<String, String>();
//									Log.d(tag, "lat :"+String.valueOf(lat)+" lon :"+String.valueOf(lon));
									GeoPoint point = new GeoPoint(lat , lon );
									geoPointList.put(name,point );
									oneUser.put("name",name);
									oneUser.put("time", time);
									
									DataOrUpdate(oneUser,point);
									
								}
								
								ifOpen = true;
								
								
								Generate_partner();
								getAndUpdateLocation();
								
								Toast.makeText(context_this_activity, "Login..", Toast.LENGTH_SHORT).show();
							}else if (status.equals("fresh_position")){
								
								/*
								 * partners 's names get here ..
								 */
//								JSONArray jsonArray = jsonInfo.getJSONArray("partners");
								Log.d(tag, "get from service");
								int lat = jsonInfo.getInt("lat");
								int lon = jsonInfo.getInt("lon");
								String name = jsonInfo.getString("name");
								String time = jsonInfo.getString("time");
//								
								
//								List<String> namesList  = new ArrayList<String>();
//								for (int i = 0; i< jsonArray.length() ; i++){
//									JSONObject onePartner = jsonArray.getJSONObject(i);
//								}
								
								HashMap<String, String> oneUser = new HashMap<String, String>();
//								Log.d(tag, "lat :"+String.valueOf(lat)+" lon :"+String.valueOf(lon));
								GeoPoint point = new GeoPoint(lat , lon );
								geoPointList.put(name,point );
								oneUser.put("name",name);
								oneUser.put("time", time);
								
								DataOrUpdate(oneUser,point);
								
								
//								String misison_idString = jsonInfo.getString("mission_id");
								
								
								
//								usersGeo.add(oneUser);
								
								getAndUpdateLocation();
								Generate_partner();
								
							}
						} catch (JSONException e) {
							// TODO Auto-generated catch block
							Log.d(tag, e.toString());
							e.printStackTrace();
						}
						
					}
				}
				
			});
		}else {
			Log.d(tag,"no initialization for broadcast");
		}
	}
	
	private void Login(){
		
		loginThread.start();
	}
	
	private void Exit(){
		Intent intent =new Intent();
		intent.putExtra(BroadCastRecevier.KEY, "OFF");
		intent.setAction(ARGUMENTS.GEO_LOCATION_SERVICE_PUSH);
		sendBroadcast(intent);
		
	}
	
	/*
	 * for mark layout
	 */
	
	public class CustomOverlay extends ItemizedOverlay<OverlayItem> {

		public CustomOverlay(Drawable mark,MapView mapView) {
			super(mark, mapView);
		}

		@Override
		public boolean onTap(GeoPoint p, MapView mapView) {
			return super.onTap(p, mapView);
		}

		/**
		 * 覆盖这个方法去处理一个item上的点击事件。 这可能是对屏幕上item的触摸点击，或者对位于中心且已选定的item的跟踪球点击。默认情况下，什么都不做，返回false
		 * 如果点击事件被处理，返回true；如果想要把这个事件传递给其它overlay，返回false
		 */
		@Override
		protected boolean onTap(int index) {
			Log.d(tag,"第" + index + "个点被点击");
			return super.onTap(index);
		}
	}
	
	/*
	 * login thread ...
	 */
	class LoginThread extends Thread{
		private int  OFF = -1;
		private int ON = 1;
		private int TAG = ON;
		@Override
		public void run() {
			// TODO Auto-generated method stub
			while (TAG == ON){
				if( ifBuild){
					if (!ifOpen && LocateFirst !=null){
						Intent intent =new Intent();
						intent.setAction(ARGUMENTS.GEO_LOCATION_SERVICE_PUSH);
						
						JSONObject infoJson = new JSONObject();
						try {
							infoJson.put("status", "log_in");
							
							String name = new Personal_Info_database(context_this_activity).searchName(uid);
							String email = new Personal_Info_database(context_this_activity).searchEmail(uid);
							infoJson.put("name", name);
							infoJson.put("email", email);
							infoJson.put("mission_id", obj_id);
							infoJson.put("time", new Date(System.currentTimeMillis()));
							int lat = LocateFirst.getLatitudeE6();
							int lon = LocateFirst.getLongitudeE6();
							infoJson.put("lat", lat);
							infoJson.put("lon", lon);
							Log.d(tag,"email :"+email+"\nname:"+name);
							ifOpen = true;
						} catch (JSONException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
						Log.d(tag, "log in info:"+infoJson);
						intent.putExtra(BroadCastRecevier.KEY, infoJson.toString());
						intent.setAction(ARGUMENTS.GEO_LOCATION_SERVICE_PUSH);
						sendBroadcast(intent);
						ifBuild =false;
						try {
							sleep(1000);
						} catch (InterruptedException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
						
					}else{
						Log.d(tag, "open aready");
						
						try {
							Thread.sleep(10000);
						} catch (InterruptedException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}
				}else{
					try {
						Thread.sleep(3000);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					Log.d(tag, "Login failed ... wait to build");
				}
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
			}
		
			if (TAG == OFF){
				try {
					Thread.sleep(50);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				Thread.interrupted();
			}
		}
		
		public void OFF(){
			TAG = OFF;
		}
		
	}
	
	private void GetLocation(){
		LocationServer = new BaiduLocationServer(context_this_activity);
		LocationServer.RunLocationServer(new BDLocationListener(){

			@Override
			public void onReceiveLocation(BDLocation result) {
				// TODO Auto-generated method stub
				if (ifOpen){
					if (LocationServer.qLocationClient == null ){
						return ;
					}
					int latitude =(int) (result.getLatitude() *1E6);
					int longitude = (int)(result.getLongitude()*1E6);
//					Log.d(tag, "lat : "+String.valueOf(latitude)+"\nlon : "+String.valueOf(longitude));
					@SuppressWarnings("deprecation")
					String timeString = new Date(System.currentTimeMillis()).toGMTString();
					
					//load all info to json ,then to send to service 
					JSONObject jsonInfo = new JSONObject();
					try {
						jsonInfo.put("status", "report_position");
						jsonInfo.put("time", timeString);
						jsonInfo.put("lat", latitude);
						jsonInfo.put("lon", longitude);
						
					} catch (JSONException e1) {
						// TODO Auto-generated catch block
						e1.printStackTrace();
					}
					
					//this is construct to send broadcast ..
					Intent intent = new Intent();
					intent.setAction(ARGUMENTS.GEO_LOCATION_SERVICE_PUSH);
					intent.putExtra(BroadCastRecevier.KEY, jsonInfo.toString());
					sendBroadcast(intent);
					
					// this is for to circle ,with sleep 5 seconds...
					try {
						Thread.sleep(4000);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}else {
					Log.d(tag, "login failed ...wait ..");
					try {
						Thread.sleep(5000);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}

			@Override
			public void onReceivePoi(BDLocation arg0) {
				// TODO Auto-generated method stub
				
			}
			
		});

	}
	private void  getFirstLocation(){
			LocationServer = new BaiduLocationServer(context_this_activity);
			LocationServer.RunLocationServer(new BDLocationListener(){

				@Override
				public void onReceiveLocation(BDLocation result) {
					// TODO Auto-generated method stub
					if (!ifOpen){
						if (LocationServer.qLocationClient == null ){
							return ;
						}
						int latitude =(int) (result.getLatitude() *1E6);
						int longitude = (int)(result.getLongitude()*1E6);
						Log.d(tag, "lat : "+String.valueOf(latitude)+"\nlon : "+String.valueOf(longitude));
						
						if (LocateFirst == null){
							GeoPoint point = new GeoPoint(latitude, longitude);
							LocateFirst = point;
							this_place = point;
							mapController.animateTo(this_place);
							// this is for to circle ,with sleep 5 seconds...
							if(LocateFirst != null){
								LocationServer.StopLocation();
							}
							
						}else{
							// this is for to circle ,with sleep 5 seconds...
							LocationServer.StopLocation();
							
							
						}
						
						LocationServer.OFF();
					
					}else {
						Log.d(tag, "this is First  login failed ...wait ..");
						try {
							Thread.sleep(2000);
						} catch (InterruptedException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}
				}

				@Override
				public void onReceivePoi(BDLocation arg0) {
					// TODO Auto-generated method stub
					
				}
				
			});
	
		
		
		
	}

	private void Generate_partner(){
		partner_bt_area.removeAllViews();
		
		for (HashMap<String, String> onePartner : usersGeo){
			Button bt = new Button(context_this_activity);
			bt.setText(onePartner.get("name"));
			final String name_this = onePartner.get("name");
			bt.setOnClickListener(new OnClickListener() {
				
				@Override
				public void onClick(View v) {
					// TODO Auto-generated method stub
					MoveToOnePointInMap(name_this);
				}
			});
			partner_bt_area.addView(bt);
		}
		partner_bt_area.setAlpha((float) 0.3);
		partner_bt_area.invalidate();
	}
	
	private void MoveToOnePointInMap(String name){
		GeoPoint onePoint = geoPointList.get(name);
		if(mapController != null){
			mapController.setCenter(onePoint);
			mapController.setZoom(13);
		}
	}
	
	private boolean DataOrUpdate(HashMap<String, String> user,GeoPoint point){
		int num =0;
		for (HashMap<String, String> one : usersGeo){
			if (user.get("name").equals(one.get("name"))){
				usersGeo.remove(num);
			}
			num++;
		}
		usersGeo.add(user);
		geoPointList.put(user.get("name"), point);
		return false;
	}
}
